package com.qdsg.ysg.doctor.service;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.Nullable;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.qdsg.ysg.doctor.R;
import com.qdsg.ysg.doctor.base.BaseApplication;
import com.qdsg.ysg.doctor.eventbus.Logout;
import com.qdsg.ysg.doctor.eventbus.WebSocket;
import com.qdsg.ysg.doctor.eventbus.WebSocketWrapper;
import com.qdsg.ysg.doctor.ui.activity.mine.WxLoginActivity;
import com.qdsg.ysg.doctor.util.JWebSocketClient;
import com.qdsg.ysg.doctor.util.ToastUtil;
import com.qdsg.ysg.doctor.util.UIConstants;
import com.rest.client.RestClient;
import com.rest.constant.JDConstant;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.java_websocket.handshake.ServerHandshake;

import java.net.URI;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import jz.joyoung.robot.util.LogUtil;
import jz.joyoung.robot.util.PreferencesHelper;

/**
 * @author Administrator
 * @date 2020/2/11
 */

public class WebSocketService extends Service {
    public JWebSocketClient client;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("aaaaaaaaaaaaaaaaaa", "onCreate  service");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            //适配安卓8.0
            NotificationChannel channel = new NotificationChannel("WebSocketService", "WebSocketService", NotificationManager.IMPORTANCE_MIN);
            channel.enableVibration(false);//去除振动

            NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            assert manager != null;
            manager.createNotificationChannel(channel);
            Notification.Builder builder = new Notification.Builder(getApplicationContext(), "WebSocketService")
//                    .setContentTitle("正在后台运行")
                    .setSmallIcon(R.mipmap.icon);
            startForeground(1, builder.build());//id must not be 0,即禁止是0
//            移除掉通知了，完美开启后台服务
            stopForeground(true);
        }
        EventBus.getDefault().register(this);
        mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);
        mHandler.postDelayed(repeatMessageRunnable, 5000);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        initSocketClient();
        return START_STICKY;
    }


    private void initSocketClient() {
        if (null == BaseApplication.currentUserId) {
            return;
        }
        URI uri = URI.create(JDConstant.WEBSOCKET_HOST + "imserver?username=" + BaseApplication.currentUserId);
        client = new JWebSocketClient(uri) {
            @Override
            public void onMessage(String message) {
                Log.e("JWebSocketClientService", "收到的消息：" + message);
//                Intent intent = new Intent();
//                intent.setAction("com.xch.servicecallback.content");
//                intent.putExtra("message", message);
//                sendBroadcast(intent);
//                checkLockAndShowNotification(message);
                WebSocketWrapper obj = JSONObject.parseObject(message, WebSocketWrapper.class);
                if (obj.command == UIConstants.WEBSOCKET_COMMAND_11) {
                    obj.data.eventFlag = 0;
                    //包含处方推送消息
                    EventBus.getDefault().postSticky(obj.data);
                    WebSocketCmd cmd = new WebSocketCmd(21, 0, BaseApplication.currentUserId, obj.data.id, obj.data.id);
                    sendMsg(JSONObject.toJSONString(cmd));
                } else if (obj.command == UIConstants.WEBSOCKET_COMMAND_20) {
                    //
                    handlerOfflineMessage(message);
                } else if (obj.cmd == UIConstants.WEBSOCKET_CMD_30) {
                    WebSocketCmd cmd = new WebSocketCmd(21, 0, BaseApplication.currentUserId, obj.id, obj.id);
                    sendMsg(JSONObject.toJSONString(cmd));
                    mHandler.post(() -> ToastUtil.showToast(WebSocketService.this, "当前患者正在通话中"));
                    EventBus.getDefault().postSticky(obj);
                } else if (obj.cmd == UIConstants.WEBSOCKET_CMD_105) {
                    Log.e("会议cmd111---", obj.cmd + "");
                    EventBus.getDefault().postSticky(obj);
                } else if (obj.cmd == UIConstants.WEBSOCKET_CMD_106) {
                    closeConnect();
                    EventBus.getDefault().postSticky(new Logout(1));
                    RestClient.getInstance().clearSession();
                    BaseApplication.currentUserId = "";
                    RestClient.getInstance().token = "";
                    PreferencesHelper.getInstance().set(WebSocketService.this, "token", "");
                    mHandler.post(() -> ToastUtil.showToast(WebSocketService.this, "你的账号在其他设备登录"));
                    startActivity(new Intent(WebSocketService.this, WxLoginActivity.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));

                } else if (obj.cmd == UIConstants.WEBSOCKET_CMD_103) {
                    WebSocketCmd cmd = new WebSocketCmd(21, 0, BaseApplication.currentUserId, obj.id, obj.id);
                    sendMsg(JSONObject.toJSONString(cmd));
                    EventBus.getDefault().postSticky(obj);
                } else if (obj.cmd == UIConstants.WEBSOCKET_CMD_102) {
                    WebSocketCmd cmd = new WebSocketCmd(21, 0, BaseApplication.currentUserId, obj.id, obj.id);
                    sendMsg(JSONObject.toJSONString(cmd));
                    mHandler.post(() -> ToastUtil.showToast(WebSocketService.this, "患者选择继续咨询"));
                } else if (obj.cmd == UIConstants.WEBSOCKET_CMD_211 || obj.cmd == UIConstants.WEBSOCKET_CMD_212) {
                    WebSocketCmd cmd = new WebSocketCmd(21, 0, BaseApplication.currentUserId, obj.id, obj.id);
                    sendMsg(JSONObject.toJSONString(cmd));
                    EventBus.getDefault().postSticky(obj);
                } else if (obj.code == 10000) {
                    EventBus.getDefault().postSticky(obj);
                    BaseApplication.runningCalls.remove(obj.clientId);
                } else if (obj.code == 10001) {
                    EventBus.getDefault().postSticky(obj);
                    BaseApplication.runningCalls.remove(obj.clientId);
                }
            }

            @Override
            public void onClose(int code, String reason, boolean remote) {
                super.onClose(code, reason, remote);
                Log.e("JWebSocketClientService", reason);
            }

            @Override
            public void onOpen(ServerHandshake handshakedata) {
                super.onOpen(handshakedata);
                Log.e("JWebSocketClientService", "websocket连接成功");
                WebSocketCmd cmd = new WebSocketCmd(19, 0, BaseApplication.currentUserId, "", "");
                sendMsg(JSONObject.toJSONString(cmd));
            }
        };
        connect();
        client.setConnectionLostTimeout(0);
    }

    /**
     * 连接websocket
     */
    private void connect() {
        new Thread() {
            @Override
            public void run() {
                try {
                    //connectBlocking多出一个等待操作，会先连接再发送，否则未连接发送会报错
                    client.connectBlocking();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }


    private void handlerOfflineMessage(String message) {
        JSONObject jsonObject = JSONObject.parseObject(message);
        JSONObject data = jsonObject.getJSONObject("data");
        JSONObject friends = data.getJSONObject("friends");

        Map<String, Object> map = new HashMap<>();
        Iterator it = friends.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, Object> entry = (Map.Entry<String, Object>) it.next();
            map.put(entry.getKey(), entry.getValue());
        }

        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String mapKey = entry.getKey();
            String mapValue = entry.getValue().toString();
//            System.out.println(mapKey + ":" + mapValue);
//            System.out.println("------------------------");
            JSONArray array = JSONArray.parseArray(mapValue);
            for (int i = 0; i < array.size(); i++) {
                WebSocket obj = JSONObject.parseObject(array.getJSONObject(i).toJSONString(), WebSocket.class);
                EventBus.getDefault().postSticky(obj);
            }
        }

    }


    /**
     * 发送消息
     */
    public void sendMsg(String msg) {
        if (null != client) {
            Log.e("JWebSocketClientService", "发送的消息：" + msg);
            try {
                client.send(msg);
            } catch (Exception ignored) {

            }
        }
    }


    /**
     * 断开连接
     */
    private void closeConnect() {
        mHandler.removeCallbacks(heartBeatRunnable);
        try {
            if (null != client) {
                client.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            client = null;
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(WebSocket webSocket) {
        if (webSocket.eventFlag == 1) {
            webSocket.createTime = System.currentTimeMillis() + "";
            webSocket.roleType = 1;
            webSocket.chatType = 2;
            webSocket.cmd = 11;
            sendMsg(JSONObject.toJSONString(webSocket));
            BaseApplication.runningCalls.put(webSocket.clientId, webSocket);
        } else if (webSocket.eventFlag == 4) {
            sendMsg(JSONObject.toJSONString(webSocket));
        }
    }


    @Override
    public void onDestroy() {
        LogUtil.e("服务onDestroy方法");
        EventBus.getDefault().unregister(this);
        closeConnect();
        super.onDestroy();
    }


    private static final long HEART_BEAT_RATE = 10 * 1000;//每隔10秒进行一次对长连接的心跳检测
    private Handler mHandler = new Handler();
    private Runnable heartBeatRunnable = new Runnable() {
        @Override
        public void run() {
            if (client != null) {
                if (client.isClosed()) {
                    reconnectWs();
                } else {
                    sendMsg("{'cmd':13,'hbbyte':'heartbeat'}");
                }
            } else {
                //如果client已为空，重新初始化websocket
                initSocketClient();
            }
            //定时对长连接进行心跳检测
            mHandler.postDelayed(this, HEART_BEAT_RATE);
        }
    };

    /**
     * 开启重连
     */
    private void reconnectWs() {
        mHandler.removeCallbacks(heartBeatRunnable);
        new Thread() {
            @Override
            public void run() {
                try {
                    //重连
                    client.reconnectBlocking();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

    private Runnable repeatMessageRunnable = new Runnable() {
        @Override
        public void run() {
            for (Map.Entry<String, WebSocket> entry : BaseApplication.runningCalls.entrySet()) {
                sendMsg(JSONObject.toJSONString(entry.getValue()));
            }
            mHandler.postDelayed(this, 5000);
        }
    };
}
